make it a static function
authorHavoc Pennington <hp@redhat.com>
Tue, 24 Oct 2000 22:44:14 +0000 (22:44 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Tue, 24 Oct 2000 22:44:14 +0000 (22:44 +0000)
2000-10-24  Havoc Pennington  <hp@redhat.com>

* gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
it a static function

* gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
redraw text when a tag is applied to it.

* gtk/gtktexttag.c (gtk_text_tag_affects_size)
(gtk_text_tag_affects_nonsize_appearance): private functions to
see if a tag requires various kinds of redraw/layout to be queued
up.

* gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock

* gtk/testtext.c (fill_example_buffer): Put the cursor
at the start of the buffer, so search works by default

* gtk/gtktextiter.c (lines_match): init match_start always

* gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
function, get iter at a line + a byte index

* gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
to set byte position within a line
(gtk_text_iter_check): remove leftover G_BREAKPOINT thing

23 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/ChangeLog
docs/reference/gtk/text_widget.sgml
gtk/gtktextbtree.c
gtk/gtktextbuffer.c
gtk/gtktextbuffer.h
gtk/gtktextiter.c
gtk/gtktextiter.h
gtk/gtktextlayout.c
gtk/gtktextmark.c
gtk/gtktextmark.h
gtk/gtktextmarkprivate.h
gtk/gtktexttag.c
gtk/gtktexttag.h
gtk/gtktexttagprivate.h
gtk/testtext.c
tests/testtext.c

index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 2f0f46c7de999c95ec9a5ee9d895ab63b48ea829..515530e8f0df801c373055a475cc9f54e3850158 100644 (file)
@@ -1,3 +1,30 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_scroll_to_mark_adjusted): make
+       it a static function
+
+       * gtk/gtktextbtree.c (gtk_text_btree_tag): Gee, maybe we should
+       redraw text when a tag is applied to it.
+
+       * gtk/gtktexttag.c (gtk_text_tag_affects_size)
+       (gtk_text_tag_affects_nonsize_appearance): private functions to
+       see if a tag requires various kinds of redraw/layout to be queued
+       up.
+
+       * gtk/gtktexttag.h (struct _GtkTextTag): Remove relief crackrock
+
+       * gtk/testtext.c (fill_example_buffer): Put the cursor 
+       at the start of the buffer, so search works by default
+
+       * gtk/gtktextiter.c (lines_match): init match_start always
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_get_iter_at_line_index): New
+       function, get iter at a line + a byte index
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_line_index): New function,
+       to set byte position within a line
+       (gtk_text_iter_check): remove leftover G_BREAKPOINT thing
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
         * gtk/testtext.c: Re-enable the "find" dialog
index 7fe274847aaeea31d98eaf2ab74ec3fa6962414c..488a60700a17e2dc59e5745ade92789d37c7cf36 100644 (file)
@@ -1,3 +1,7 @@
+2000-10-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/text_widget.sgml: add note about UTF-8
+
 2000-10-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtk-sections.txt: remove GtkTextBTree
index 776f0795330226059b3f6909d5ef1c7203c071eb..80cd81d2e61b603e4cfd1e628dda8520d27a491a 100644 (file)
@@ -21,6 +21,16 @@ display a <link linkend="GtkTextBuffer">GtkTextBuffer</link>. Each buffer can be
 displayed by any number of views.
 </para>
 
+<para>
+One of the important things to remember about text in GTK+ is that it's in the
+UTF-8 encoding. This means that one character can be encoded as multiple
+bytes. Character counts are usually referred to as
+<firstterm>offsets</firstterm>, while byte counts are called
+<firstterm>indexes</firstterm>. If you confuse these two, things will work fine
+with ASCII, but as soon as your buffer contains multibyte characters, bad things
+will happen.
+</para>
+
 <para>
 Text in a buffer can be marked with <firstterm>tags</firstterm>. A tag is an
 attribute that can be applied to some range of text. For example, a tag might be
index dcb569360657bdb768bd7aa72660a09dba17cdbe..5b1f98430b72e7132143386c20e354c52020e790 100644 (file)
@@ -172,8 +172,8 @@ struct _GtkTextBTree {
   GtkTextTagTable *table;
   GHashTable *mark_table;
   guint refcount;
-  GtkTextLineSegment *insert_mark;
-  GtkTextLineSegment *selection_bound_mark;
+  GtkTextMark *insert_mark;
+  GtkTextMark *selection_bound_mark;
   GtkTextBuffer *buffer;
   BTreeView *views;
   GSList *tag_infos;
@@ -321,6 +321,9 @@ static GtkTextTagInfo *gtk_text_btree_get_existing_tag_info (GtkTextBTree   *tre
 static void            gtk_text_btree_remove_tag_info       (GtkTextBTree   *tree,
                                                              GtkTextTag     *tag);
 
+static void redisplay_region (GtkTextBTree      *tree,
+                              const GtkTextIter *start,
+                              const GtkTextIter *end);
 
 /* Inline thingies */
 
@@ -421,33 +424,36 @@ gtk_text_btree_new (GtkTextTagTable *table,
   
   {
     GtkTextIter start;
-
+    GtkTextLineSegment *seg;
+    
     gtk_text_btree_get_iter_at_line_char(tree, &start, 0, 0);
     
 
-    tree->insert_mark =
-      (GtkTextLineSegment*) gtk_text_btree_set_mark(tree,
-                                                    NULL,
-                                                    "insert",
-                                                    FALSE,
-                                                    &start,
-                                                    FALSE);
+    tree->insert_mark = gtk_text_btree_set_mark (tree,
+                                                 NULL,
+                                                 "insert",
+                                                 FALSE,
+                                                 &start,
+                                                 FALSE);
+
+    seg = tree->insert_mark->segment;
     
-    tree->insert_mark->body.mark.not_deleteable = TRUE;
-    tree->insert_mark->body.mark.visible = TRUE;
+    seg->body.mark.not_deleteable = TRUE;
+    seg->body.mark.visible = TRUE;
     
-    tree->selection_bound_mark =
-      (GtkTextLineSegment*) gtk_text_btree_set_mark(tree,
-                                                    NULL,
-                                                    "selection_bound",
-                                                    FALSE,
-                                                    &start,
-                                                    FALSE);
-
-    tree->selection_bound_mark->body.mark.not_deleteable = TRUE;
+    tree->selection_bound_mark = gtk_text_btree_set_mark (tree,
+                                                          NULL,
+                                                          "selection_bound",
+                                                          FALSE,
+                                                          &start,
+                                                          FALSE);
+
+    seg = tree->selection_bound_mark->segment;
     
-    _mark_segment_ref(tree->insert_mark);
-    _mark_segment_ref(tree->selection_bound_mark);
+    seg->body.mark.not_deleteable = TRUE;
+
+    g_object_ref (G_OBJECT (tree->insert_mark));
+    g_object_ref (G_OBJECT (tree->selection_bound_mark));
   }
 
   tree->refcount = 1;
@@ -467,7 +473,11 @@ gtk_text_btree_ref (GtkTextBTree *tree)
 static void
 mark_destroy_foreach (gpointer key, gpointer value, gpointer user_data)
 {
-  _mark_segment_unref (value);
+  GtkTextLineSegment *seg = value;
+
+  g_return_if_fail (seg->body.mark.tree == NULL);
+  
+  g_object_unref (G_OBJECT (seg->body.mark.obj));
 }
 
 void
@@ -479,26 +489,26 @@ gtk_text_btree_unref (GtkTextBTree *tree)
   tree->refcount -= 1;
 
   if (tree->refcount == 0)
-    {      
-      gtk_text_btree_node_destroy(tree, tree->root_node);
+    {
+      gtk_text_btree_node_destroy (tree, tree->root_node);
 
-      g_hash_table_foreach(tree->mark_table,
-                           mark_destroy_foreach,
-                           NULL);
-      g_hash_table_destroy(tree->mark_table);
+      g_hash_table_foreach (tree->mark_table,
+                            mark_destroy_foreach,
+                            NULL);
+      g_hash_table_destroy (tree->mark_table);
       
-      _mark_segment_unref(tree->insert_mark);
-      _mark_segment_unref(tree->selection_bound_mark);
+      g_object_unref (G_OBJECT (tree->insert_mark));
+      g_object_unref (G_OBJECT (tree->selection_bound_mark));
 
-      gtk_signal_disconnect(GTK_OBJECT(tree->table),
-                            tree->tag_changed_handler);
+      gtk_signal_disconnect (GTK_OBJECT(tree->table),
+                             tree->tag_changed_handler);
 
-      gtk_signal_disconnect(GTK_OBJECT(tree->table),
-                            tree->tag_removed_handler);
+      gtk_signal_disconnect (GTK_OBJECT(tree->table),
+                             tree->tag_removed_handler);
       
-      gtk_object_unref(GTK_OBJECT(tree->table));
+      gtk_object_unref (GTK_OBJECT(tree->table));
 
-      g_free(tree);
+      g_free (tree);
     }
 }
 
@@ -1382,8 +1392,8 @@ gtk_text_btree_get_view_size (GtkTextBTree *tree,
   g_return_if_fail(tree != NULL);
   g_return_if_fail(view_id != NULL);
   
-  gtk_text_btree_node_get_size(tree->root_node, view_id,
-                              width, height);  
+  gtk_text_btree_node_get_size (tree->root_node, view_id,
+                                width, height);  
 }
 
 /*
@@ -1461,6 +1471,26 @@ iter_stack_invert(IterStack *stack)
     }
 }
 
+static void
+queue_tag_redisplay (GtkTextBTree      *tree,
+                     GtkTextTag        *tag,
+                     const GtkTextIter *start,
+                     const GtkTextIter *end)
+{
+  if (gtk_text_tag_affects_size (tag))
+    {
+      gtk_text_btree_invalidate_region (tree, start, end);
+               
+    }
+  else if (gtk_text_tag_affects_nonsize_appearance (tag))
+    {
+      /* We only need to queue a redraw, not a relayout */
+      redisplay_region (tree, start, end);
+    }
+
+  /* We don't need to do anything if the tag doesn't affect display */
+}
+
 void
 gtk_text_btree_tag (const GtkTextIter *start_orig,
                     const GtkTextIter *end_orig,
@@ -1502,6 +1532,8 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
   
   tree = gtk_text_iter_get_btree(&start);
 
+  queue_tag_redisplay (tree, tag, &start, &end);
+  
   info = gtk_text_btree_get_tag_info(tree, tag);
   
   start_line = gtk_text_iter_get_text_line(&start);
@@ -2311,21 +2343,23 @@ redisplay_region (GtkTextBTree      *tree,
       if (ld)
        end_y += ld->height;
          
-      gtk_text_layout_changed (view->layout, start_y, end_y - start_y, end_y - start_y);
+      gtk_text_layout_changed (view->layout, start_y,
+                               end_y - start_y,
+                               end_y - start_y);
 
       view = view->next;
     }
 }
 
 static void
-redisplay_mark(GtkTextLineSegment *mark)
+redisplay_mark (GtkTextLineSegment *mark)
 {
   GtkTextIter iter;
   GtkTextIter end;
     
   gtk_text_btree_get_iter_at_mark(mark->body.mark.tree,
                                   &iter,
-                                  (GtkTextMark*)mark);
+                                  mark->body.mark.obj);
 
   end = iter;
   gtk_text_iter_next_char(&end);
@@ -2370,10 +2404,10 @@ real_set_mark(GtkTextBTree *tree,
   g_return_val_if_fail(gtk_text_iter_get_btree(where) == tree, NULL);
 
   if (existing_mark)
-    mark = (GtkTextLineSegment*) existing_mark;
+    mark = existing_mark->segment;
   else if (name != NULL)
-    mark = g_hash_table_lookup(tree->mark_table,
-                               name);
+    mark = g_hash_table_lookup (tree->mark_table,
+                                name);
   else
     mark = NULL;
   
@@ -2391,12 +2425,13 @@ real_set_mark(GtkTextBTree *tree,
   if (mark != NULL)
     {
       if (redraw_selections &&
-         (mark == tree->insert_mark ||
-          mark == tree->selection_bound_mark))
+         (mark == tree->insert_mark->segment ||
+          mark == tree->selection_bound_mark->segment))
        {
          GtkTextIter old_pos;
 
-         gtk_text_btree_get_iter_at_mark (tree, &old_pos, (GtkTextMark*)mark);
+         gtk_text_btree_get_iter_at_mark (tree, &old_pos,
+                                           mark->body.mark.obj);
          redisplay_region (tree, &old_pos, where);
        }
       
@@ -2411,7 +2446,7 @@ real_set_mark(GtkTextBTree *tree,
         }
 
       /* Redraw the mark's old location. */
-      redisplay_mark_if_visible(mark);
+      redisplay_mark_if_visible (mark);
       
       /* Unlink mark from its current location.
          This could hose our iterator... */
@@ -2432,22 +2467,22 @@ real_set_mark(GtkTextBTree *tree,
       mark->body.mark.line = gtk_text_iter_get_text_line(&iter);
 
       if (mark->body.mark.name)
-        g_hash_table_insert(tree->mark_table,
-                            mark->body.mark.name,
-                            mark);
+        g_hash_table_insert (tree->mark_table,
+                             mark->body.mark.name,
+                             mark);
     }
   
   /* Link mark into new location */
-  gtk_text_btree_link_segment(mark, &iter);
+  gtk_text_btree_link_segment (mark, &iter);
   
   /* Invalidate some iterators. */
-  segments_changed(tree);
+  segments_changed (tree);
   
   /*
    * update the screen at the mark's new location.
    */
 
-  redisplay_mark_if_visible(mark);
+  redisplay_mark_if_visible (mark);
 
   return mark;
 }
@@ -2461,9 +2496,13 @@ gtk_text_btree_set_mark (GtkTextBTree *tree,
                          const GtkTextIter *iter,
                          gboolean should_exist)
 {
-  return (GtkTextMark*)real_set_mark(tree, existing_mark,
-                                     name, left_gravity, iter, should_exist,
-                                     TRUE);  
+  GtkTextLineSegment *seg;
+
+  seg = real_set_mark(tree, existing_mark,
+                      name, left_gravity, iter, should_exist,
+                      TRUE);
+
+  return seg ? seg->body.mark.obj : NULL;
 }
 
 gboolean
@@ -2474,9 +2513,9 @@ gtk_text_btree_get_selection_bounds (GtkTextBTree *tree,
   GtkTextIter tmp_start, tmp_end;
   
   gtk_text_btree_get_iter_at_mark (tree, &tmp_start,
-                                   (GtkTextMark*)tree->insert_mark);
+                                   tree->insert_mark);
   gtk_text_btree_get_iter_at_mark (tree, &tmp_end,
-                                   (GtkTextMark*)tree->selection_bound_mark);
+                                   tree->selection_bound_mark);
   
   if (gtk_text_iter_equal(&tmp_start, &tmp_end))
     {
@@ -2512,10 +2551,10 @@ gtk_text_btree_place_cursor(GtkTextBTree      *tree,
     redisplay_region(tree, &start, &end);
   
   /* Move insert AND selection_bound before we redisplay */
-  real_set_mark(tree, (GtkTextMark*) tree->insert_mark,
-                "insert", FALSE, iter, TRUE, FALSE);
-  real_set_mark(tree, (GtkTextMark*) tree->selection_bound_mark,
-                "selection_bound", FALSE, iter, TRUE, FALSE);
+  real_set_mark (tree, tree->insert_mark,
+                 "insert", FALSE, iter, TRUE, FALSE);
+  real_set_mark (tree, tree->selection_bound_mark,
+                 "selection_bound", FALSE, iter, TRUE, FALSE);
 }
 
 void
@@ -2537,11 +2576,13 @@ void
 gtk_text_btree_remove_mark (GtkTextBTree *tree,
                             GtkTextMark *mark)
 {
-  GtkTextLineSegment *segment = (GtkTextLineSegment*) mark;
+  GtkTextLineSegment *segment;
   
-  g_return_if_fail (segment != NULL);
+  g_return_if_fail (mark != NULL);
   g_return_if_fail (tree != NULL);
 
+  segment = mark->segment;
+  
   if (segment->body.mark.not_deleteable)
     {
       g_warning("Can't delete special mark `%s'", segment->body.mark.name);
@@ -2553,8 +2594,9 @@ gtk_text_btree_remove_mark (GtkTextBTree *tree,
   
   if (segment->body.mark.name)
     g_hash_table_remove (tree->mark_table, segment->body.mark.name);
-  
-  _mark_segment_unref (segment);
+
+  /* Remove the ref on the mark that belonged to the segment. */
+  g_object_unref (G_OBJECT (mark));
 
   segment->body.mark.tree = NULL;
   segment->body.mark.line = NULL;
@@ -2564,24 +2606,28 @@ gboolean
 gtk_text_btree_mark_is_insert (GtkTextBTree *tree,
                                GtkTextMark *segment)
 {
-  return segment == (GtkTextMark*) tree->insert_mark;
+  return segment == tree->insert_mark;
 }
 
 gboolean
 gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree,
                                         GtkTextMark *segment)
 {
-  return segment == (GtkTextMark*) tree->selection_bound_mark;
+  return segment == tree->selection_bound_mark;
 }
 
 GtkTextMark*
 gtk_text_btree_get_mark_by_name (GtkTextBTree *tree,
                                  const gchar *name)
 {
+  GtkTextLineSegment *seg;
+  
   g_return_val_if_fail(tree != NULL, NULL);
   g_return_val_if_fail(name != NULL, NULL);
 
-  return g_hash_table_lookup(tree->mark_table, name);
+  seg = g_hash_table_lookup (tree->mark_table, name);
+
+  return seg ? seg->body.mark.obj : NULL;
 }
 
 void
@@ -2592,7 +2638,7 @@ gtk_text_mark_set_visible (GtkTextMark       *mark,
   
   g_return_if_fail(mark != NULL);
   
-  seg = (GtkTextLineSegment*)mark;
+  seg = mark->segment;
 
   if (seg->body.mark.visible == setting)
     return;
@@ -4964,7 +5010,15 @@ gtk_text_btree_node_destroy(GtkTextBTree *tree, GtkTextBTreeNode *node)
             {
               seg = line->segments;
               line->segments = seg->next;
-              (*seg->type->deleteFunc)(seg, line, 1);
+
+              if (GTK_IS_TEXT_MARK_SEGMENT (seg))
+                {
+                  /* Set the mark as deleted */
+                  seg->body.mark.tree = NULL;
+                  seg->body.mark.line = NULL;
+                }
+                  
+              (*seg->type->deleteFunc) (seg, line, 1);
             }
           gtk_text_line_destroy(tree, line);
         }
@@ -4977,12 +5031,13 @@ gtk_text_btree_node_destroy(GtkTextBTree *tree, GtkTextBTreeNode *node)
         {
           childPtr = node->children.node;
           node->children.node = childPtr->next;
-          gtk_text_btree_node_destroy(tree, childPtr);
+          gtk_text_btree_node_destroy (tree, childPtr);
         }
     }
-  summary_list_destroy(node->summary);
-  node_data_list_destroy(node->node_data);
-  g_free(node);
+  
+  summary_list_destroy (node->summary);
+  node_data_list_destroy (node->node_data);
+  g_free (node);
 }
 
 static NodeData*
@@ -5111,15 +5166,16 @@ get_tree_bounds(GtkTextBTree *tree,
 }
   
 static void
-tag_changed_cb(GtkTextTagTable *table,
-               GtkTextTag *tag,
-               gboolean size_changed,
-               GtkTextBTree *tree)
+tag_changed_cb (GtkTextTagTable *table,
+                GtkTextTag      *tag,
+                gboolean         size_changed,
+                GtkTextBTree    *tree)
 {
   if (size_changed)
     {
-      /* We need to queue a redisplay on all regions that are tagged with
-         this tag. */
+      /* We need to queue a relayout on all regions that are tagged with
+       * this tag.
+       */
 
       GtkTextIter start;
       GtkTextIter end;
@@ -5127,14 +5183,15 @@ tag_changed_cb(GtkTextTagTable *table,
       if (gtk_text_btree_get_iter_at_first_toggle(tree, &start, tag))
         {
           /* Must be a last toggle if there was a first one. */
-          gtk_text_btree_get_iter_at_last_toggle(tree, &end, tag);
-          gtk_text_btree_invalidate_region(tree,
-                                           &start, &end);
+          gtk_text_btree_get_iter_at_last_toggle (tree, &end, tag);
+          gtk_text_btree_invalidate_region (tree,
+                                            &start, &end);
                
         }
     }
   else
     {
+      /* We only need to queue a redraw, not a relayout */
       BTreeView *view;
       
       view = tree->views;
index a686a4531f3b21a94404b6cd1a81329a1787bb1c..557bd6bf5c722ddca3eaf7caf78fa8809c2b232c 100644 (file)
@@ -1072,14 +1072,14 @@ gtk_text_buffer_mark_set (GtkTextBuffer     *buffer,
      this signal is purely for notification, and not to allow users
      to modify the default behavior. */
 
-  gtk_text_mark_ref (mark);
+  g_object_ref (G_OBJECT (mark));
   
   gtk_signal_emit(GTK_OBJECT(buffer),
                   signals[MARK_SET],
                   location,
                   mark);
 
-  gtk_text_mark_unref (mark);
+  g_object_unref (G_OBJECT (mark));
 }
 
 /**
@@ -1107,12 +1107,12 @@ gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
   GtkTextIter location;
   GtkTextMark *mark;
   
-  mark = gtk_text_btree_set_mark(get_btree (buffer),
-                                 existing_mark,
-                                 mark_name,
-                                 left_gravity,
-                                 iter,
-                                 should_exist);
+  mark = gtk_text_btree_set_mark (get_btree (buffer),
+                                  existing_mark,
+                                  mark_name,
+                                  left_gravity,
+                                  iter,
+                                  should_exist);
 
   if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
       gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
@@ -1126,7 +1126,7 @@ gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
   
   gtk_text_buffer_mark_set (buffer, &location, mark);
 
-  return (GtkTextMark*)mark;
+  return mark;
 }
 
 /**
@@ -1182,7 +1182,7 @@ gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
                            GtkTextMark *mark,
                            const GtkTextIter *where)
 {
-  g_return_if_fail (mark != NULL);
+  g_return_if_fail (GTK_IS_TEXT_MARK (mark));
   g_return_if_fail (!gtk_text_mark_get_deleted (mark));
   g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
   
@@ -1202,7 +1202,7 @@ gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
                                   GtkTextIter *iter,
                                   GtkTextMark *mark)
 {
-  g_return_if_fail (mark != NULL);
+  g_return_if_fail (GTK_IS_TEXT_MARK (mark));
   g_return_if_fail (!gtk_text_mark_get_deleted (mark));
   g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
 
@@ -1218,7 +1218,7 @@ gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
  * 
  * Deletes @mark, so that it's no longer located anywhere in the
  * buffer. Removes the reference the buffer holds to the mark, so if
- * you haven't called gtk_text_mark_ref() the mark will be freed. Even
+ * you haven't called g_object_ref() on the mark, it will be freed. Even
  * if the mark isn't freed, most operations on @mark become
  * invalid. There is no way to undelete a
  * mark. gtk_text_mark_get_deleted() will return TRUE after this
@@ -1230,11 +1230,11 @@ void
 gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
                             GtkTextMark   *mark)
 {
-  g_return_if_fail (mark != NULL);
+  g_return_if_fail (GTK_IS_TEXT_MARK (mark));
   g_return_if_fail (!gtk_text_mark_get_deleted (mark));
   g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
   
-  gtk_text_mark_ref (mark);
+  g_object_ref (G_OBJECT (mark));
   
   gtk_text_btree_remove_mark (get_btree (buffer), mark);
 
@@ -1245,7 +1245,7 @@ gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
   gtk_signal_emit (GTK_OBJECT(buffer), signals[MARK_DELETED],
                    mark);
 
-  gtk_text_mark_unref (mark);
+  g_object_unref (G_OBJECT (mark));
 }
 
 /**
@@ -1616,11 +1616,24 @@ gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer      *buffer,
                                          gint                line_number,
                                          gint                char_offset)
 {  
-  g_return_if_fail(iter != NULL);
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+
+  gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
+                                        iter, line_number, char_offset);
+}
+
+void
+gtk_text_buffer_get_iter_at_line_index  (GtkTextBuffer *buffer,
+                                         GtkTextIter   *iter,
+                                         gint           line_number,
+                                         gint           byte_index)
+{
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_line_char(get_btree (buffer),
-                                       iter, line_number, char_offset);
+  gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
+                                        iter, line_number, byte_index);
 }
 
 void
index d35eb9a4f7b0f1fff7be9911464bb2871be45294..920d09d2e9924f77ae7bf752b715aee28eccb2e8 100644 (file)
@@ -263,6 +263,10 @@ void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
                                               GtkTextIter   *iter,
                                               gint           line_number,
                                               gint           char_offset);
+void gtk_text_buffer_get_iter_at_line_index  (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter,
+                                              gint           line_number,
+                                              gint           byte_index);
 void gtk_text_buffer_get_iter_at_offset      (GtkTextBuffer *buffer,
                                               GtkTextIter   *iter,
                                               gint           char_offset);
index 70ac5f19e8d8613e4dcedee3ce43d92046f04a6a..32f85be9a2347a8a7a45ef9e2d4228de93e83d92 100644 (file)
@@ -134,7 +134,7 @@ iter_set_from_segment(GtkTextRealIter *iter,
       seg = seg->next;
     }
 
-  iter_set_from_byte_offset(iter, line, byte_offset);
+  iter_set_from_byte_offset (iter, line, byte_offset);
 }
 
 /* This function ensures that the segment-dependent information is
@@ -667,7 +667,7 @@ gtk_text_iter_get_line_offset(const GtkTextIter *iter)
  * Return value: distance from start of line, in bytes
  **/
 gint
-gtk_text_iter_get_line_index(const GtkTextIter *iter)
+gtk_text_iter_get_line_index (const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -898,7 +898,7 @@ gtk_text_iter_get_marks (const GtkTextIter *iter)
     {
       if (seg->type == &gtk_text_left_mark_type ||
           seg->type == &gtk_text_right_mark_type)
-        retval = g_slist_prepend(retval, (GtkTextMark*)seg);
+        retval = g_slist_prepend (retval, seg->body.mark.obj);
       
       seg = seg->next;
     }
@@ -2477,7 +2477,35 @@ gtk_text_iter_set_line_offset(GtkTextIter *iter,
 }
 
 void
-gtk_text_iter_set_line(GtkTextIter *iter, gint line_number)
+gtk_text_iter_set_line_index (GtkTextIter *iter,
+                              gint         byte_on_line)
+{
+  GtkTextRealIter *real;
+  
+  g_return_if_fail (iter != NULL);
+  
+  real = gtk_text_iter_make_surreal (iter);
+
+  if (real == NULL)
+    return;
+
+  check_invariants (iter);
+  
+  iter_set_from_byte_offset (real, real->line, byte_on_line);
+
+  if (real->segment->type == &gtk_text_char_type &&
+      (real->segment->body.chars[real->segment_byte_offset] & 0xc0) == 0x80)
+    g_warning ("%s: Incorrect byte offset %d falls in the middle of a UTF-8 "
+               "character; this will crash the text buffer. "
+               "Byte indexes must refer to the start of a character.",
+               G_STRLOC, byte_on_line);
+  
+  check_invariants (iter);
+}
+
+void
+gtk_text_iter_set_line (GtkTextIter *iter,
+                        gint         line_number)
 {
   GtkTextLine *line;
   gint real_line;
@@ -2861,6 +2889,9 @@ lines_match (const GtkTextIter *start,
   
   if (*lines == NULL || **lines == '\0')
     {
+      if (match_start)
+        *match_start = *start;
+      
       if (match_end)
         *match_end = *start;
       return TRUE;
@@ -2904,7 +2935,7 @@ lines_match (const GtkTextIter *start,
     }
 
   if (found == NULL)
-    {
+    {      
       g_free (line_text);
       return FALSE;
     }
@@ -2924,7 +2955,7 @@ lines_match (const GtkTextIter *start,
       forward_chars_with_skipping (match_start, offset,
                                    visible_only, !slice);
     }
-
+  
   /* Go to end of search string */
   offset += g_utf8_strlen (*lines, -1);
 
@@ -3234,9 +3265,9 @@ gtk_text_btree_get_iter_at_line_char (GtkTextBTree *tree,
 
 void
 gtk_text_btree_get_iter_at_line_byte (GtkTextBTree   *tree,
-                                     GtkTextIter    *iter,
-                                     gint            line_number,
-                                     gint            byte_index)
+                                      GtkTextIter    *iter,
+                                      gint            line_number,
+                                      gint            byte_index)
 {
   GtkTextRealIter *real = (GtkTextRealIter*)iter;
   GtkTextLine *line;
@@ -3252,6 +3283,13 @@ gtk_text_btree_get_iter_at_line_byte (GtkTextBTree   *tree,
   /* We might as well cache this, since we know it. */
   real->cached_line_number = real_line;
 
+  if (real->segment->type == &gtk_text_char_type &&
+      (real->segment->body.chars[real->segment_byte_offset] & 0xc0) == 0x80)
+    g_warning ("%s: Incorrect byte offset %d falls in the middle of a UTF-8 "
+               "character; this will crash the text buffer. "
+               "Byte indexes must refer to the start of a character.",
+               G_STRLOC, byte_index); 
+  
   check_invariants(iter);
 }
 
@@ -3336,32 +3374,34 @@ gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
   g_return_val_if_fail(iter != NULL, FALSE);
   g_return_val_if_fail(tree != NULL, FALSE);
   
-  mark = gtk_text_btree_get_mark_by_name(tree, mark_name);
+  mark = gtk_text_btree_get_mark_by_name (tree, mark_name);
 
   if (mark == NULL)
     return FALSE;
   else
     {
-      gtk_text_btree_get_iter_at_mark(tree, iter, mark);
-      check_invariants(iter);
+      gtk_text_btree_get_iter_at_mark (tree, iter, mark);
+      check_invariants (iter);
       return TRUE;
     }
 }
 
 void
 gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
-                                  GtkTextIter *iter,
-                                  GtkTextMark *mark)
+                                 GtkTextIter *iter,
+                                 GtkTextMark *mark)
 {
-  GtkTextLineSegment *seg = (GtkTextLineSegment*) mark;
+  GtkTextLineSegment *seg;
   
-  g_return_if_fail(iter != NULL);
-  g_return_if_fail(tree != NULL);
-  g_return_if_fail(GTK_IS_TEXT_MARK (mark));
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (tree != NULL);
+  g_return_if_fail (GTK_IS_TEXT_MARK (mark));
+
+  seg = mark->segment;
   
-  iter_init_from_segment(iter, tree,
-                         seg->body.mark.line, seg);
-  g_assert(seg->body.mark.line == gtk_text_iter_get_text_line(iter));
+  iter_init_from_segment (iter, tree,
+                          seg->body.mark.line, seg);
+  g_assert (seg->body.mark.line == gtk_text_iter_get_text_line(iter));
   check_invariants(iter);
 }
 
@@ -3431,10 +3471,6 @@ gtk_text_iter_check (const GtkTextIter *iter)
          real->line_byte_offset,
          real->line_char_offset);
 #endif
-
-  if (real->line_byte_offset == 97 &&
-      real->line_char_offset == 95)
-    G_BREAKPOINT();
   
   if (segments_updated)
     {
index 8e6eeaecdd61a978202462b05b1aa4fe2b13f3e6..9a49dfbfab99dc2e45ee700503d888b732358e94 100644 (file)
@@ -160,6 +160,8 @@ void     gtk_text_iter_set_line           (GtkTextIter *iter,
                                            gint         line_number);
 void     gtk_text_iter_set_line_offset    (GtkTextIter *iter,
                                            gint         char_on_line);
+void     gtk_text_iter_set_line_index     (GtkTextIter *iter,
+                                           gint         byte_on_line);
 void     gtk_text_iter_forward_to_end     (GtkTextIter *iter);
 gboolean gtk_text_iter_forward_to_newline (GtkTextIter *iter);
 
index d4b57f973a66f4ba8b341b5f9c2af9f4306df2fc..99e3c39c408cf3000fbc286b0c0f21694b5583b5 100644 (file)
@@ -1211,7 +1211,7 @@ add_cursor (GtkTextLayout      *layout,
    * user has hidden the cursor.
    */
   if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
-                                     (GtkTextMark*)seg) &&
+                                     seg->body.mark.obj) &&
       (!layout->cursor_visible ||
        gtk_text_buffer_get_selection_bounds (layout->buffer, NULL, NULL)))
     return;
index a1a4c6f65fbab1e6d643e94bafc7b800aab29cf2..c66af21e2fc5c939881f924cf83c1aaa39d50b18 100644 (file)
 
 #include "gtktextbtree.h"
 
-gboolean
-gtk_text_mark_is_visible(GtkTextMark *mark)
+static void gtk_text_mark_init       (GtkTextMark      *mark);
+static void gtk_text_mark_class_init (GtkTextMarkClass *klass);
+static void gtk_text_mark_finalize   (GObject          *obj);
+
+
+static gpointer parent_class = NULL;
+
+GType
+gtk_text_mark_get_type (void)
 {
-  GtkTextLineSegment *seg;
+  static GType object_type = 0;
 
-  seg = (GtkTextLineSegment*)mark;
+  if (!object_type)
+    {
+      static const GTypeInfo object_info =
+      {
+        sizeof (GtkTextMarkClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gtk_text_mark_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (GtkTextMark),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) gtk_text_mark_init,
+      };
+      
+      object_type = g_type_register_static (G_TYPE_OBJECT,
+                                            "GtkTextMark",
+                                            &object_info);
+    }
+  
+  return object_type;
+}
 
-  return seg->body.mark.visible;
+static void
+gtk_text_mark_init (GtkTextMark *mark)
+{
+  mark->segment = NULL;
 }
 
-const char *
-gtk_text_mark_get_name (GtkTextMark *mark)
+static void
+gtk_text_mark_class_init (GtkTextMarkClass *klass)
 {
-  GtkTextLineSegment *seg;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  seg = (GtkTextLineSegment*)mark;
+  parent_class = g_type_class_peek_parent (klass);
 
-  return seg->body.mark.name;
+  object_class->finalize = gtk_text_mark_finalize;
 }
 
-
-GtkTextMark *
-gtk_text_mark_ref (GtkTextMark *mark)
+static void
+gtk_text_mark_finalize (GObject *obj)
 {
+  GtkTextMark *mark;
   GtkTextLineSegment *seg;
 
-  seg = (GtkTextLineSegment*)mark;
+  mark = GTK_TEXT_MARK (obj);
 
-  _mark_segment_ref (seg);
+  seg = mark->segment;
 
-  return mark;
+  if (seg)
+    {
+      g_return_if_fail (seg->body.mark.tree == NULL);
+
+      if (seg->body.mark.tree != NULL)
+        g_warning ("GtkTextMark being finalized while still in the buffer; "
+                   "someone removed a reference they didn't own! Crash "
+                   "impending");
+      
+      g_free (seg->body.mark.name);
+      g_free (seg);
+
+      mark->segment = NULL;
+    }
 }
 
-void
-gtk_text_mark_unref (GtkTextMark *mark)
+gboolean
+gtk_text_mark_is_visible(GtkTextMark *mark)
 {
   GtkTextLineSegment *seg;
 
-  seg = (GtkTextLineSegment*)mark;
-  
-  _mark_segment_unref (seg);
+  seg = mark->segment;
+
+  return seg->body.mark.visible;
+}
+
+const char *
+gtk_text_mark_get_name (GtkTextMark *mark)
+{
+  GtkTextLineSegment *seg;
+
+  seg = mark->segment;
+
+  return seg->body.mark.name;
 }
 
 gboolean
@@ -100,7 +154,10 @@ gtk_text_mark_get_deleted (GtkTextMark *mark)
   
   g_return_val_if_fail (mark != NULL, FALSE);
 
-  seg = (GtkTextLineSegment*)mark;
+  seg = mark->segment;
+
+  if (seg == NULL)
+    return TRUE;
   
   return seg->body.mark.tree == NULL;
 }
@@ -127,52 +184,23 @@ _mark_segment_new (GtkTextBTree *tree,
     mark->type = &gtk_text_left_mark_type;
   else
     mark->type = &gtk_text_right_mark_type;
-
+  
   mark->byte_count = 0;
   mark->char_count = 0;
 
+  mark->body.mark.obj = g_object_new (GTK_TYPE_TEXT_MARK, NULL);
+  mark->body.mark.obj->segment = mark;
+  
   mark->body.mark.tree = tree;
   mark->body.mark.line = NULL;
   mark->next = NULL;
 
-  mark->body.mark.refcount = 1;
-
   mark->body.mark.visible = FALSE;
   mark->body.mark.not_deleteable = FALSE;
   
   return mark;
 }
 
-void
-_mark_segment_ref (GtkTextLineSegment *mark)
-{
-  g_return_if_fail (mark != NULL);
-  g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
-                    mark->type == &gtk_text_left_mark_type);
-  g_return_if_fail (mark->body.mark.refcount > 0);
-  
-  mark->body.mark.refcount += 1;
-}
-
-void
-_mark_segment_unref (GtkTextLineSegment *mark)
-{
-  g_return_if_fail (mark != NULL);
-  g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
-                    mark->type == &gtk_text_left_mark_type);
-  g_return_if_fail (mark->body.mark.refcount > 0);
-
-  mark->body.mark.refcount -= 1;
-
-  if (mark->body.mark.refcount == 0)
-    {
-      g_free(mark->body.mark.name);
-      
-      g_free(mark);
-    }
-}
-
-
 static int                 mark_segment_delete_func  (GtkTextLineSegment *segPtr,
                                                       GtkTextLine        *line,
                                                       int                 treeGone);
index 0ee018063933ee546cfd3a0e03dd9b30f9ec2320..45255f4459547ea5472d5ffc00ad99cd3b0443bc 100644 (file)
@@ -56,15 +56,36 @@ extern "C" {
 
 /* The GtkTextMark data type */
 
-typedef struct _GtkTextMark GtkTextMark;
+typedef struct _GtkTextMark      GtkTextMark;
+typedef struct _GtkTextMarkClass GtkTextMarkClass;
+
+#define GTK_TYPE_TEXT_MARK              (gtk_text_mark_get_type ())
+#define GTK_TEXT_MARK(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_TEXT_MARK, GtkTextMark))
+#define GTK_TEXT_MARK_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_MARK, GtkTextMarkClass))
+#define GTK_IS_TEXT_MARK(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_TEXT_MARK))
+#define GTK_IS_TEXT_MARK_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_MARK))
+#define GTK_TEXT_MARK_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TEXT_MARK, GtkTextMarkClass))
+
+struct _GtkTextMark
+{
+  GObject parent_instance;  
+
+  gpointer segment;
+};
+
+struct _GtkTextMarkClass
+{
+  GObjectClass parent_class;
+
+};
+
+GType        gtk_text_mark_get_type   (void) G_GNUC_CONST;
 
 void         gtk_text_mark_set_visible (GtkTextMark *mark,
                                         gboolean     setting);
 gboolean     gtk_text_mark_is_visible  (GtkTextMark *mark);
 /* FIXME gconst */
-const char * gtk_text_mark_get_name    (GtkTextMark *mark);
-GtkTextMark *gtk_text_mark_ref         (GtkTextMark *mark);
-void         gtk_text_mark_unref       (GtkTextMark *mark);
+const char  *gtk_text_mark_get_name    (GtkTextMark *mark);
 gboolean     gtk_text_mark_get_deleted (GtkTextMark *mark);
 
 
index 87e862c289fada7dec91b5985dc5a7a561a794d2..4776ca6b10be57151804274b0fabc3b3cdc3e153 100644 (file)
@@ -8,7 +8,7 @@ extern "C" {
 #include <gtk/gtktexttypes.h>
 #include <gtk/gtktextlayout.h>
 
-#define GTK_IS_TEXT_MARK(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
+#define GTK_IS_TEXT_MARK_SEGMENT(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
                                 ((GtkTextLineSegment*)mark)->type == &gtk_text_right_mark_type)
 
 /*
@@ -17,7 +17,7 @@ extern "C" {
  */
 
 struct _GtkTextMarkBody {
-  guint refcount;
+  GtkTextMark *obj;
   gchar *name;
   GtkTextBTree *tree;
   GtkTextLine *line;
@@ -28,9 +28,6 @@ struct _GtkTextMarkBody {
 GtkTextLineSegment *_mark_segment_new   (GtkTextBTree       *tree,
                                          gboolean            left_gravity,
                                          const gchar        *name);
-void                _mark_segment_ref   (GtkTextLineSegment *mark);
-void                _mark_segment_unref (GtkTextLineSegment *mark);
-
 
 #ifdef __cplusplus
 }
index 54d91d0bf2d899922e8cd8355a1ec99b78afff35..d769aa3decc60f1443be53b3920b72cb939f99ec 100644 (file)
@@ -1233,10 +1233,7 @@ gtk_text_attributes_fill_from_tags(GtkTextAttributes *dest,
           dest->appearance.bg_color = vals->appearance.bg_color;
           
           dest->appearance.draw_bg = TRUE;
-        }      
-
-      if (tag->relief_set)
-        dest->relief = vals->relief;
+        }
 
       if (tag->bg_stipple_set)
         {
@@ -1327,3 +1324,38 @@ gtk_text_attributes_fill_from_tags(GtkTextAttributes *dest,
       ++n;
     }
 }
+
+gboolean
+gtk_text_tag_affects_size (GtkTextTag *tag)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
+
+  return 
+    tag->font_set ||
+    tag->justify_set ||
+    tag->left_margin_set ||
+    tag->left_wrapped_line_margin_set ||
+    tag->offset_set ||
+    tag->right_margin_set ||
+    tag->pixels_above_lines_set ||
+    tag->pixels_below_lines_set ||
+    tag->pixels_inside_wrap_set ||
+    tag->tabs_set ||
+    tag->underline_set ||
+    tag->wrap_mode_set ||
+    tag->invisible_set;
+}
+
+gboolean
+gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_TAG (tag), FALSE);
+
+  return
+    tag->bg_color_set ||
+    tag->bg_stipple_set ||
+    tag->fg_color_set ||
+    tag->fg_stipple_set ||
+    tag->strikethrough_set ||
+    tag->bg_full_height_set;
+}
index 91a0591f3075c41a91684ee1bcd37ebec2772a20..0465fb9a3913201148b67db01a071164d3da3c53 100644 (file)
@@ -31,7 +31,8 @@ typedef struct _GtkTextAttributes GtkTextAttributes;
 typedef struct _GtkTextTag GtkTextTag;
 typedef struct _GtkTextTagClass GtkTextTagClass;
 
-struct _GtkTextTag {
+struct _GtkTextTag
+{
   GtkObject parent_instance;
 
   GtkTextTagTable *table;
@@ -58,7 +59,6 @@ struct _GtkTextTag {
    * this tag does not affect it.
    */
   guint bg_color_set : 1;
-  guint relief_set : 1;
   guint bg_stipple_set : 1;
   guint fg_color_set : 1;
   guint font_set : 1;
@@ -139,7 +139,6 @@ struct _GtkTextAttributes
 
   GtkTextAppearance appearance;
   
-  GtkShadowType relief;
   GtkJustification justify;
   GtkTextDirection direction;
   
index 200864503bd5deef3a93d7d659f62ab02a0c7434..3e95017af9015fc36d9a129631eb337e61ae4a90 100644 (file)
@@ -23,4 +23,7 @@ void                gtk_text_attributes_unrealize (GtkTextAttributes *values,
                                                    GdkColormap       *cmap,
                                                    GdkVisual         *visual);
 
+gboolean gtk_text_tag_affects_size               (GtkTextTag *tag);
+gboolean gtk_text_tag_affects_nonsize_appearance (GtkTextTag *tag);
+
 #endif
index d813d6fed4599bf4e38fe80d30de3b0f3b40772d..dcc363b6fe9f4437da13b7b88e51e2a4b084b72f 100644 (file)
@@ -421,6 +421,10 @@ fill_example_buffer (GtkTextBuffer *buffer)
   GdkPixbuf *pixbuf;
   int i;
   char *str;
+
+  /* FIXME this is broken if called twice on a buffer, since
+   * we try to create tags a second time.
+   */
   
   tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
@@ -581,9 +585,13 @@ fill_example_buffer (GtkTextBuffer *buffer)
   g_object_unref (G_OBJECT (pixbuf));
   
   printf ("%d lines %d chars\n",
-        gtk_text_buffer_get_line_count (buffer),
-        gtk_text_buffer_get_char_count (buffer));
+          gtk_text_buffer_get_line_count (buffer),
+          gtk_text_buffer_get_char_count (buffer));
 
+  /* Move cursor to start */
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+  gtk_text_buffer_place_cursor (buffer, &iter);
+  
   gtk_text_buffer_set_modified (buffer, FALSE);
 }
 
index d813d6fed4599bf4e38fe80d30de3b0f3b40772d..dcc363b6fe9f4437da13b7b88e51e2a4b084b72f 100644 (file)
@@ -421,6 +421,10 @@ fill_example_buffer (GtkTextBuffer *buffer)
   GdkPixbuf *pixbuf;
   int i;
   char *str;
+
+  /* FIXME this is broken if called twice on a buffer, since
+   * we try to create tags a second time.
+   */
   
   tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
@@ -581,9 +585,13 @@ fill_example_buffer (GtkTextBuffer *buffer)
   g_object_unref (G_OBJECT (pixbuf));
   
   printf ("%d lines %d chars\n",
-        gtk_text_buffer_get_line_count (buffer),
-        gtk_text_buffer_get_char_count (buffer));
+          gtk_text_buffer_get_line_count (buffer),
+          gtk_text_buffer_get_char_count (buffer));
 
+  /* Move cursor to start */
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+  gtk_text_buffer_place_cursor (buffer, &iter);
+  
   gtk_text_buffer_set_modified (buffer, FALSE);
 }